#ifndef VTreeSql_H
#define VTreeSql_H

#include "VSqlDatabase.h"
#include "VTreeNode.h"

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

class VTreeSqlMaps
{
public:
	enum EDbStatus
	{
		EDbStatus_actual  = 0,
		EDbStatus_deleted = 1000
	};
	static QString SqlStatusActual(const QString &tableAlias = "");

public:
	static QString itemTypeToDb(VItem::EItemType v);
	static VItem::EItemType dbToItemType(const QString &v);

	static bool    itemTypeIsDbTableName(VItem::EItemType v);
	static QString itemTypeToDbTableName(VItem::EItemType v);
	
public:
	struct VDbStruct
	{
		QString dbTableName;
		QString dbFieldName;
		QString pkDbFieldName;
		QString pkPropName;
		bool    enEdit;
	};
	//typedef QMap<QString,VDbStruct> TDbStruct;
	static bool dbStruct(VItem *item,int propIndex,VDbStruct &out);

	static QString sqlDataField(const QString &unicode,VItem::EItemType itemType)
	{
		return QString(
			"left join %1 %2 on %2.idRec = rec.idRec and %2.idNavAttr = "
			"("
				"select vnav.idNav "
				"from VidNav vnav "
				"left join VidName vname on vnav.idName = vname.idName "
				"where vname.unicod = '%3' "
			")"
		)
		.arg(itemTypeToDbTableName(itemType))
		.arg(unicode)
		.arg(unicode);
	}	

	static QString sqlDataTable(const QString &unicode)
	{
		return QString(
			"(rec.idNavCat = ("
				"select vnav.idNav "
				"from VidNav vnav "
				"left join VidName vname on vnav.idName = vname.idName "
				"where vname.unicod = '%1' "
			"))"
		)
		.arg(unicode);
	}

private:
	struct VMaps
	{
		VMaps();
		
		QMap<VItem::EItemType,QString> m_itemTypeToDb;
		QMap<QString,VItem::EItemType> m_dbToItemType;
		QMap<VItem::EItemType,QString> m_itemTypeToDbTableName;
		//QMap<QString,TDbStruct> m_dbStruct;
	};
	static VMaps m_maps;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

class VTreeSqlGenId
{
public:
	VTreeSqlGenId(QSqlDatabase& db);

	bool exec(int &outId);

private:
	QSqlQuery m_query;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

class VTreeSqlInsertName
{
public:
	VTreeSqlInsertName(QSqlDatabase& db);
	
	bool exec(VItem *item);
	
private:
	QSqlQuery m_query;
};

///////////////////////////////////////////////////////////////////////////////

class VTreeSqlInsertNode
{
public:
	VTreeSqlInsertNode(QSqlDatabase& db);

	bool exec(VItem *parentItem,VItem *item);

private:
	QSqlQuery m_query;
};

///////////////////////////////////////////////////////////////////////////////

class VTreeSqlInsertNodeBA
{
public:
	enum BA { before,after };
	
public:
	VTreeSqlInsertNodeBA(QSqlDatabase& db);

	bool exec(VItem *currentItem,VItem *insertItem,BA ba);

private:
	QSqlQuery m_query;
};

///////////////////////////////////////////////////////////////////////////////

class VTreeSqlMoveNode
{
public:
	enum BAC { before,after,child };

public:
	VTreeSqlMoveNode(QSqlDatabase& db);

	bool exec(VItem *moveItem,VItem *currentItem,BAC bac);

private:
	QSqlQuery m_query;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

class VTreeSqlDeleteNode
{
public:
	VTreeSqlDeleteNode(QSqlDatabase& db);

	bool exec(VItem *item);

private:
	QSqlQuery m_query;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

class VTreeSqlHasChildren
{
public:
	VTreeSqlHasChildren(QSqlDatabase& db);
	
	bool exec(VItem *item);
	
private:
	QSqlQuery m_query;
};

///////////////////////////////////////////////////////////////////////////////

class VTreeSqlSelectChildrenNode
{
public:
	VTreeSqlSelectChildrenNode(QSqlDatabase& db);

	bool exec(VTreeNode *parentNode,QList<VTreeNode*> &children);

private:
	QSqlQuery m_query;
	VTreeSqlHasChildren m_hasChildren;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

class VTreeSqlUpdateNode
{
public:
	VTreeSqlUpdateNode(QSqlDatabase& db);

	bool exec(VItem *item,int propIndex);

private:
	QSqlQuery m_query;
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

class VDataSqlInsertRecord
{
public:
	VDataSqlInsertRecord(QSqlDatabase& db);

	bool exec(VTreeNode *node,VDataRecord &outRecord);

private:
	QSqlDatabase &m_db;
	QSqlQuery m_query;
	VTreeSqlGenId m_genId;
};

///////////////////////////////////////////////////////////////////////////////

class VDataSqlDeleteRecord
{
public:
	VDataSqlDeleteRecord(QSqlDatabase& db);

	bool exec(VTreeNode *node,int idRec);

private:
	QSqlDatabase &m_db;
};

///////////////////////////////////////////////////////////////////////////////

class VDataSqlUpdateValue
{
public:
	VDataSqlUpdateValue(QSqlDatabase& db);

	bool exec(VTreeNode *nodeField,int idRec,VDataField *dataField);

private:
	QSqlDatabase &m_db;
};

///////////////////////////////////////////////////////////////////////////////

class VDataSqlSelectRecords
{
public:
	VDataSqlSelectRecords(QSqlDatabase& db);

	bool exec(VTreeNode *node,QList<VDataRecord*> &outRecords);

private:
	QSqlDatabase &m_db;
};

///////////////////////////////////////////////////////////////////////////////

#endif
